iT邦幫忙

2022 iThome 鐵人賽

DAY 2
0
Mobile Development

Android app 效能優化系列 第 2

從背景處理優化效能

  • 分享至 

  • xImage
  •  

如果我們在主執行緒(Main thread、UI thread)上執行耗時的工作,例如檔案讀寫、資料庫操作、網路操作等,UI 就會沒有反應,甚至產生 ANR。解決的方式是簡單的使用 Coroutine 將耗時的任務在背景執行。

lifecycleScope.launch {
    //跟後端取得資料
    val data = networkCall()
    //回到UI執行緒
    binding.result.text = data
}

private suspend fun networkCall(): String {
    return withContext(Dispatchers.IO) {
        //在Background thread執行
		//模擬2秒後取得資料
        delay(2000)
        "Data1"
    }
}

只是將耗時工作放到背景 (Background thread) 處理,對於某些情境仍是不夠的。這種在背景執行的工作,預期使用者會在你的App中等待工作完成。一但遇到執行的工作需要更多的時間,使用者就會離開 App,而這個在背景執行的工作,並不能保證一定會執行完成。

使用正確的服務來執行背景任務

我們把會在app執行的背景任務,區分為這幾種來看:

  1. 需要立即執行
  2. 需要長時間執行
  3. 需要持續性執行
  4. 可延後執行
  5. 週期性任務
  6. 在特定時間執行

需要立即執行

需要立即執行的背景任務,例如檔案讀寫、資料庫操作、網路操作等等,這幾種背景任務的執行一般都是做完就結束了,所以使用 Background thread 即可。

需要長時間執行

當任務的執行需要更長的時間,使用者就可能離開 App。因此需要一個在 App離開時仍可以在背景處理的WorkManager。例如你在Line要傳送影片給朋友,傳送影片並非馬上就能完成,使用者也可能先離開 App。透過WorkManager 就可以達到使用者離開App時仍在背景傳送影片。

需要持續性執行

有一種背景工作是需要持續性的執行,例如音樂撥放、語音通話、視訊通話。這種就需要使用 Foreground service。Foreground service 可以在你離開App時持續的在背景工作,直到我們停止這個工作。也因為這是持續性的,較耗效能,所以會在通知列顯示這個工作正在執行,例如你在kkbox撥放音樂,就會在通知例看到音樂正在撥放。

可延後執行

有些工作不需要在當下立即執行,就可以透過 WorkManager來延後執行。而這個工作需要在離開app後仍被執行,且執行的結果不用馬上讓使用者知道。例如你搜集了使用者使用App的資訊,將這些數據發送至後端伺服器。這就是一個可以延後再執行的工作。

週期性任務

當任務為週期性時,而且要在離開App時仍可以執行,就可以使用 PeriodicWorkRequest 來執行週期性的任務,這個週期性任務最短週期為15分鐘一次。也避免你自已寫一個在背景執行的計時器造成資源浪費。例如每隔半小時需要與後端同步一次資訊就很適合使用 PeriodicWorkRequest。

在特定時間執行

如果這個任務只需要在特定的時間執行,便使用 Alarm 來達成。即使你的 App 已經不在前景執行,或是裝置已經進到閒置狀態,仍可以在指定的時間執行指定的工作。你不要自已設定一個計時器,或一直在背景執行。

總結一下這幾種工作的類型:
背景工作的類型
選擇適當的服務來執行不同情境的工作,就是希望你不要一直佔用資源。只在需要的時候執行工作,而不是在背景持續的執行。當 App 在前景時,基本上要做什麼都可以,一但裝置進到閒置狀況,Android 就會限制你的使用行為,畢竟使用者不會接受沒在用手機時候,手機卻依然是耗電的。

參考:

https://developer.android.com/guide/background
https://developer.android.com/training/scheduling/alarms
https://developer.android.com/topic/libraries/architecture/workmanager/basics


上一篇
Android app 效能優化
下一篇
ANR 應用程式沒有回應
系列文
Android app 效能優化30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言